-- Assignment 3
-- 
-- When executed, this creates a file called "sudoku.html" in the same directory.
-- This file contains a random sudoku and its solution (which is initially
-- hidden).
--
-- Indication of time spent: 3.5 man hours

module SudokuWebsite where 

import Data.List
import System.IO
import Sudoku2
import RandomSudoku

main :: IO()
main = do
  [solution] <- rsolveNs [emptyN]
  problem <- genProblem solution
  grid2website (sud2grid (fst problem)) (sud2grid (fst solution)) "sudoku.html"

grid2website :: Grid -> Grid -> String -> IO()
grid2website problem solution filePath = do
  handle <- openFile filePath WriteMode
  hPutStrLn handle "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" "
  hPutStrLn handle "  \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"
  hPutStrLn handle "<html xmlns=\"http://www.w3.org/1999/xhtml\">"
  hPutStrLn handle "<head>"
  hPutStrLn handle "  <title>Sudoku Website</title>"
  hPutStrLn handle "  <style type=\"text/css\">"
  hPutStrLn handle "    td { width: 25px; height: 25px; text-align: center; }"
  hPutStrLn handle "    td.borderRight { border-right: 3px solid black; }"
  hPutStrLn handle "    td.borderBottom { border-bottom: 3px solid black; }"
  hPutStrLn handle "  </style>"
  hPutStrLn handle "</head>"
  hPutStrLn handle "<body>"
  hPutStrLn handle (grid2html problem)
  hPutStrLn handle "<br /><br />"
  hPutStrLn handle "<a href=\"javascript:showSolution()\">Show solution</a>"
  hPutStrLn handle "<div id=\"solution\">"
  hPutStrLn handle (grid2html solution)
  hPutStrLn handle "</div>"
  hPutStrLn handle "<script type=\"text/javascript\">"
  hPutStrLn handle "  function showSolution() {"
  hPutStrLn handle "    document.getElementById('solution').style.display = 'block';"
  hPutStrLn handle "  }"
  hPutStrLn handle "  document.getElementById('solution').style.display = 'none';"
  hPutStrLn handle "</script>"
  hPutStrLn handle "</body>"
  hPutStrLn handle "</html>"
  hClose handle

grid2html :: Grid -> String
grid2html grid = 
  "<table border=\"1\" cellpadding=\"0\" cellspacing=\"0\">\n" ++ 
  unlines [row2html (grid !! row) row | row <- [0..8] ] ++ 
  "</table>\n"

row2html :: [Value] -> Int -> String
row2html values index = 
  "<tr>\n" ++ 
  unlines [value2html (values !! col) index col | col <- [0..8] ] ++ 
  "</tr>\n"

value2html :: Value -> Int -> Int -> String
value2html val row col = "<td class=\"" ++ cssForCell row col ++"\">\n" ++ 
                         symbolForCell val ++ 
                         "</td>\n"

symbolForCell :: Value -> String
symbolForCell 0 = "&nbsp;"
symbolForCell val = show val

cssForCell :: Int -> Int -> String
cssForCell row col = if (borderBottom row) && (borderRight col)
                     then "borderBottom borderRight"
                     else if (borderBottom row)
                          then "borderBottom"
                          else if (borderRight col)
                               then "borderRight"
                               else ""
  where
    borderBottom :: Int -> Bool
    borderBottom row = (row + 1) `mod` 3 == 0 && row < 8
    borderRight :: Int -> Bool
    borderRight col = (col + 1) `mod` 3 == 0 && col < 8
